# 
# <copyright file="deploy.ps1" company="The MITRE Corporation">
#    Copyright (c) 2010 The MITRE Corporation. All rights reserved.
# </copyright>
# 
################################################/
# deploy.ps1 - Deploys an IC.NET server with private settings
# Project: IC.NET Installer
# Author: Don McGarry
################################################/

# Copyright (c) 2013 The MITRE Corporation. All rights reserved.
#
# NOTICE
# This software was produced for the U. S. Government
# under Contract No. FA8721-09-C-0001, and is
# subject to the Rights in Noncommercial Computer Software
# and Noncommercial Computer Software Documentation Clause
# (DFARS) 252.227-7014 (JUN 1995)

# Function to import security certificates.

# NOTE: To get a list of available store names, run the following command: 
# dir cert: | Select -Expand StoreNames

# Example Usages:
# Import-Certificate -CertFile "VeriSign_Expires-2028.08.01.cer" -StoreNames AuthRoot, Root -LocalMachine

# Import-Certificate -CertFile "VeriSign_Expires-2018.05.18.p12" -StoreNames AuthRoot -LocalMachine -CurrentUser -CertPassword Password -Verbose

# dir -Path C:\Certs -Filter *.cer | Import-Certificate -CertFile $_ -StoreNames AuthRoot, Root -LocalMachine -Verbose
#requires -Version 2.0
# From http://poshcode.org/1937
function Import-Certificate
{
	param
	(
		[IO.FileInfo] $CertFile = $(throw "Paramerter -CertFile [System.IO.FileInfo] is required."),
		[string[]] $StoreNames = $(throw "Paramerter -StoreNames [System.String] is required."),
		[switch] $LocalMachine,
		[switch] $CurrentUser,
		[string] $CertPassword,
		[switch] $Verbose
	)
	
	begin
	{
		[void][System.Reflection.Assembly]::LoadWithPartialName("System.Security")
	}
	
	process 
	{
        if ($Verbose)
		{
            $VerbosePreference = 'Continue'
        }
    
		if (-not $LocalMachine -and -not $CurrentUser)
		{
			Write-Warning "One or both of the following parameters are required: '-LocalMachine' '-CurrentUser'. Skipping certificate '$CertFile'."
		}

		try
		{
			if ($_)
            {
                $certfile = $_
            }
            $cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 $certfile,$CertPassword
		}
		catch
		{
			Write-Error ("Error importing '$certfile': $_ .") -ErrorAction:Continue
		}
			
		if ($cert -and $LocalMachine)
		{
			$StoreScope = "LocalMachine"
			$StoreNames | ForEach-Object {
				$StoreName = $_
				if (Test-Path "cert:\$StoreScope\$StoreName")
				{
					try
					{
						$store = New-Object System.Security.Cryptography.X509Certificates.X509Store $StoreName, $StoreScope
						$store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadWrite)
						$store.Add($cert)
						$store.Close()
						Write-Verbose "Successfully added '$certfile' to 'cert:\$StoreScope\$StoreName'."
					}
					catch
					{
						Write-Error ("Error adding '$certfile' to 'cert:\$StoreScope\$StoreName': $_ .") -ErrorAction:Continue
					}
				}
				else
				{
					Write-Warning "Certificate store '$StoreName' does not exist. Skipping..."
				}
			}
		}
		
		if ($cert -and $CurrentUser)
		{
			$StoreScope = "CurrentUser"
			$StoreNames | ForEach-Object {
				$StoreName = $_
				if (Test-Path "cert:\$StoreScope\$StoreName")
				{
					try
					{
						$store = New-Object System.Security.Cryptography.X509Certificates.X509Store $StoreName, $StoreScope
						$store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadWrite)
						$store.Add($cert)
						$store.Close()
						Write-Verbose "Successfully added '$certfile' to 'cert:\$StoreScope\$StoreName'."
					}
					catch
					{
						Write-Error ("Error adding '$certfile' to 'cert:\$StoreScope\$StoreName': $_ .") -ErrorAction:Continue
					}
				}
				else
				{
					Write-Warning "Certificate store '$StoreName' does not exist. Skipping..."
				}
			}
		}
		
		if($cert)
		{
			return $cert.Thumbprint
		}
	}
	
	end
	{ }
}

# http://docs.amazonwebservices.com/AmazonS3/latest/dev/RESTAuthentication.html#RESTAuthenticationQueryStringAuth

#Signature = URL-Encode( Base64( HMAC-SHA1( YourSecretAccessKeyID, UTF-8-Encoding-Of( StringToSign ) ) ) );

#StringToSign = HTTP-VERB + "\n" +
# Content-MD5 + "\n" + # is empty for s3 request
# Content-Type + "\n" + # is empty for s3 request
# Expires + "\n" +
# CanonicalizedAmzHeaders +
# CanonicalizedResource; # relative URL kinda?

function get-s3Url ($server, $resourceUrl, $accessKey, $secretKey, $expireDate)
{
$s3BaseTime = [System.DateTime]::Parse("1970-01-01T00:00:00.0000000Z")
$exipires = [Convert]::ToInt32($expireDate.Subtract($s3BaseTime).TotalSeconds).ToString()
$stringToSign = "GET`n" + "`n" + "`n" + "$exipires`n" + "$resourceUrl"

$sha = new-object System.Security.Cryptography.HMACSHA1
$utf8 = New-Object System.Text.utf8encoding
$sha.Key = $utf8.Getbytes($secretKey)
$seedBytes = $utf8.GetBytes($stringToSign)
$digest = $sha.ComputeHash($seedBytes)
$base64Encoded = [Convert]::Tobase64String($digest)
$null = [Reflection.Assembly]::LoadWithPartialName("System.Web")
$urlEncoded = [System.Web.HttpUtility]::UrlEncode($base64Encoded)

$fullUrl = $server + $resourceUrl + "?AWSAccessKeyId=" + $accessKey + "&Expires=" + $exipires + "&Signature=" + $urlEncoded
$fullUrl
}


$installerdir=split-path $SCRIPT:MyInvocation.MyCommand.Path -parent
$installerdir="$installerdir\"
Write-Host "Installer Directory: "$installerdir
. $installerdir"install_vars.ps1"
#. $installerdir"s3url.ps1"

if(!(Test-Path $DLInstallerDir))
{
	New-Item $DLInstallerDir -itemtype directory
}

if(!(Test-Path $SQLInstallerDir))
{
	New-Item $SQLInstallerDir -itemtype directory
}

if(!(Test-Path $NETInstallerDir))
{
	New-Item $NETInstallerDir -itemtype directory
}

$webclient = New-Object System.Net.WebClient
Write-Host "Modifying Folder View Properties and restarting explorer.exe..."
$key = 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced'
Set-ItemProperty $key Hidden 1
Set-ItemProperty $key HideFileExt 0
Set-ItemProperty $key ShowSuperHidden 1
Stop-Process -processname explorer

if((C:\Chocolatey\chocolateyinstall\chocolatey.ps1 version GoogleChrome).verMessage -ne "Latest Version Installed")
{
	Write-Host "Installing Chrome..."
    &cinst GoogleChrome
	Write-Host "Chrome Installed..."
	if($AnyKey -eq 1)
	{
		Write-Host "Press any key to continue ..."
		$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
	}
}

if((C:\Chocolatey\chocolateyinstall\chocolatey.ps1 version 7zip.install).verMessage -ne "Latest Version Installed")
{
	Write-Host "Installing 7zip..."
    &cinst 7zip.install
	Write-Host "7zip Installed..."
	if($AnyKey -eq 1)
	{
		Write-Host "Press any key to continue ..."
		$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
	}
}

if((C:\Chocolatey\chocolateyinstall\chocolatey.ps1 version notepadplusplus.install).verMessage -ne "Latest Version Installed")
{
	Write-Host "Installing Notepad++..."
    &cinst notepadplusplus.install
	Write-Host "Notepad++ Installed..."
	if($AnyKey -eq 1)
	{
		Write-Host "Press any key to continue ..."
		$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
	}
}

if(!(Test-Path "C:\Program Files (x86)\Cyberduck"))
{
	Write-Host "Installing Cyberduck++..."
    #Install Cyberduck
    $filename="Cyberduck-Installer-4.4.3.exe"
    $resourceUrl = "$bucketpath$filename"
    $expires = [System.DateTime]::Now.AddMinutes(60)
    $url = get-s3Url $s3endpoint $resourceUrl $accessKey $secretKey $expires
    Write-Host "S3 Encoded URL: "$url
    $file = "$DLInstallerDir$filename"
    Write-Host "Filename: "$file
    if(!(Test-Path $file))
    {
		$webclient.DownloadFile($url,$file)
    }

    & $file /S | Out-Null
	Write-Host "Cyberduck Installed..."
	if($AnyKey -eq 1)
	{
		Write-Host "Press any key to continue ..."
		$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
	}
}

$env:Path="$env:path;${Env:ProgramFiles}\7-Zip\"

#Download SQL Server ISO & Extract
Write-Host "Downloading SQL Server Installer"
	if($AnyKey -eq 1)
	{
		Write-Host "Press any key to continue ..."
		$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
	}
$filename=$SQLfilename
$resourceUrl = "$bucketpath$filename"
$expires = [System.DateTime]::Now.AddMinutes(60)
$url = get-s3Url $s3endpoint $resourceUrl $accessKey $secretKey $expires
Write-Host "S3 Encoded URL: "$url
$file = "$SQLInstallerDir$filename"
Write-Host "Filename: "$file
if(!(Test-Path $file))
{
	$webclient.DownloadFile($url,$file)
}

Write-Host "SQL Server Installer Downloaded"
Write-Host "Expanding SQL Server Installer"
if($AnyKey -eq 1)
{
	Write-Host "Press any key to continue ..."
	$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
}

$SQLExtract=$SQLInstallerDir+"SQLInst\"
$SQLSetupExe=$SQLExtract+"Setup.exe"

if(!(Test-Path $SQLExtract))
{
	&7z x $file -o"$SQLExtract" -aoa
}

Write-Host "SQL Server Installer Expanded"
Write-Host "Checking if .NET is installed"
	if($AnyKey -eq 1)
	{
		Write-Host "Press any key to continue ..."
		$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
	}
#If .NET needed, download it
$nets=Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP' -recurse |
Get-ItemProperty -name Version -EA 0 |
Where { $_.PSChildName -match '^(?!S)\p{L}'} 
$netinstalled=$false
foreach($net in $nets)
{
    Write-Host ".NET Name: "$net.PSChildName
    Write-Host ".NET Version: "$net.Version
    if(($net.PSChildName -eq "FULL") -and (($net.Version -eq "4.0.30319") -or ($net.Version -eq "4.5.50938") -or ($net.Version -eq "4.5.51641")))
    {
        $netinstalled=$true
    }
}
if(!$netinstalled)
{
    Write-Host "Fetching .NET"
	if($AnyKey -eq 1)
	{
		Write-Host "Press any key to continue ..."
		$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
	}
	$filename=$NETFileName
	$resourceUrl = "$bucketpath$filename"
	$expires = [System.DateTime]::Now.AddMinutes(60)
	$url = get-s3Url $s3endpoint $resourceUrl $accessKey $secretKey $expires
	Write-Host "S3 Encoded URL: "$url
	$file = "$NETInstallerDir$filename"
    Write-Host "Filename: "$file
	if(!(Test-Path $file))
	{
		$webclient.DownloadFile($url,$file)
	}
	
	Write-Host ".NET Downloaded"
	if($AnyKey -eq 1)
	{
		Write-Host "Press any key to continue ..."
		$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
	}
	$NETSetupExe=$file
	if($AnyKey -eq 1)
	{
		Write-Host "Press any key to continue ..."
		$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
	}
}

#Download URL Rewrite
Write-Host "Downloading URL Rewrite Installer"
	if($AnyKey -eq 1)
	{
		Write-Host "Press any key to continue ..."
		$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
	}
$filename=$URLRewriteInstall
$resourceUrl = "$bucketpath$filename"
$expires = [System.DateTime]::Now.AddMinutes(60)
$url = get-s3Url $s3endpoint $resourceUrl $accessKey $secretKey $expires
Write-Host "S3 Encoded URL: "$url
$file = "$DLInstallerDir$filename"
Write-Host "Filename: "$file
if(!(Test-Path $file))
{
	$webclient.DownloadFile($url,$file)
}
$URLRewriteInstall=$file

Write-Host "URL Rewrite Installer Downloaded"

Write-Host "Fetching IC.NET Installer"
if($AnyKey -eq 1)
{
	Write-Host "Press any key to continue ..."
	$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
}
$filename=$ICNETInstallerFile
$resourceUrl = "$bucketpath$filename"
$expires = [System.DateTime]::Now.AddMinutes(60)
$url = get-s3Url $s3endpoint $resourceUrl $accessKey $secretKey $expires
Write-Host "S3 Encoded URL: "$url
$file = "$DLInstallerDir$filename"
Write-Host "Filename: "$file
if(Test-Path $file)
{
	Remove-Item $file -force
}

$webclient.DownloadFile($url,$file)
Write-Host "IC.NET Installer Downloaded"
Write-Host "Expanding & Running Installer"
if($AnyKey -eq 1)
{
	Write-Host "Press any key to continue ..."
	$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
}

&7z x $file -o"$DLInstallerDir"\ICNET"" -aoa
. $DLInstallerDir"ICNET\Install.ps1" $NetSvc $Username $Password $DBInstallPath $DBLogInstallPath $icnetIISPath $icnetInstallPath $RESTAppPool $ServiceAppPool $IISSite $Port $SQLInstallType $SAPass $SQLSetupExe $SQLPID $NETSetupExe $IISSvcSite $icnetIISSvcPath $SvcPort
$installerdir=split-path $SCRIPT:MyInvocation.MyCommand.Path -parent
$installerdir="$DLInstallerDir\"
Write-Host "Creating Local User"
if($AnyKey -eq 1)
{
	Write-Host "Press any key to continue ..."
	$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
}

. $installerdir"ICNET/Scripts/CreateUser.ps1" $LocalUserName $LocalUserPass
$group = [ADSI]"WinNT://./Administrators,group"
$group.Add("WinNT://$LocalUserName,user")
$group = [ADSI]"WinNT://./Users,group"
$group.Add("WinNT://$LocalUserName,user")

if($DoSSL -eq 1)
{
	Write-Host "Doing SSL..."
	$env:Path="$env:path;${Env:ProgramFiles}\7-Zip\"
	if($AnyKey -eq 1)
	{
		Write-Host "Press any key to continue ..."
		$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
	}
	Import-Module WebAdministration
	#. $installerdir"Import-Certificate.ps1"
	Write-Host "Fetching CA Certs"
	if($AnyKey -eq 1)
	{
		Write-Host "Press any key to continue ..."
		$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
	}
	$filename=$CACertsZip
	$resourceUrl = "$bucketpath$filename"
	$expires = [System.DateTime]::Now.AddMinutes(60)
	$url = get-s3Url $s3endpoint $resourceUrl $accessKey $secretKey $expires
	Write-Host "S3 Encoded URL: "$url
	$file = "$installerdir$filename"
	Write-Host "Filename: "$file
	if(Test-Path $file)
	{
		Remove-Item $file -force
	}
	
	$webclient.DownloadFile($url,$file)
	&7z x $file -o"$installerdir"\CA"" -aoa
	Write-Host "Installing CA Certs..."
	if($AnyKey -eq 1)
	{
		Write-Host "Press any key to continue ..."
		$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
	}
	$certFile = get-childitem $installerdir"\CA" | where {$_.Extension -match "cer"} 
	if ($certFile -ne $NULL) 
	{ 
		#Add all certs in downloaded zip to Root CA Store
		"Discovered a .cer in the same folder as this script, installing it in the LocalMachine\Root certificate store.." 
		$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2($certFile.FullName) 
		$store = get-item Cert:\LocalMachine\Root 
		$store.Open("ReadWrite") 
		$store.Add($cert) 
		$store.Close() 
	}
	
	New-WebBinding -Name $IISSite -IP "*" -Port $SSLPort -Protocol https
	Get-WebBinding -Name $IISSite -Port $Port | Remove-WebBinding
	
	Write-Host "Fetching SSL Cert"
	if($AnyKey -eq 1)
	{
		Write-Host "Press any key to continue ..."
		$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
	}
	$filename=$SSLCert
	$resourceUrl = "$bucketpath$filename"
	$expires = [System.DateTime]::Now.AddMinutes(60)
	$url = get-s3Url $s3endpoint $resourceUrl $accessKey $secretKey $expires
	Write-Host "S3 Encoded URL: "$url
	$file = "$installerdir$filename"
	Write-Host "Filename: "$file
	if(Test-Path $file)
	{
		Remove-Item $file -force
	}
	
	$webclient.DownloadFile($url,$file)
	Write-Host "Installing SSL Cert..."
	if($AnyKey -eq 1)
	{
		Write-Host "Press any key to continue ..."
		$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
	}
	$thumb=Import-Certificate -CertFile $file -StoreNames My -LocalMachine -CertPassword $SSLCertPW -Verbose
	Get-Item cert:\LocalMachine\MY\$thumb | new-item IIS:\SslBindings\0.0.0.0!443
}